package org.cloud.im.admin.processor;

import org.cloud.im.admin.handler.StoreHandler;
import org.cloud.im.core.ImChannelContext;
import org.cloud.im.core.ImConst;
import org.cloud.im.core.packets.LoginReqBody;
import org.cloud.im.core.packets.LoginRespBody;
import org.cloud.im.core.packets.User;
import org.cloud.im.core.utils.Md5;
import org.cloud.im.server.processor.login.LoginCmdProcessor;
import org.cloud.im.server.protocol.AbstractProtocolCmdProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @Author: w.weidong.lin@abite.com
 * @Description: 登录服务处理
 * @Date: create in 2021/10/20 9:17
 */
public class LoginServiceProcessor extends AbstractProtocolCmdProcessor implements LoginCmdProcessor {

    private Logger logger = LoggerFactory.getLogger(LoginServiceProcessor.class);

    public static final Map<String, User> tokenMap = new HashMap<>();

    /**
     * 根据用户名和密码获取用户
     *
     * @param loginReqBody
     * @param imChannelContext
     * @return
     * @author: WChao
     */
    public User getUser(LoginReqBody loginReqBody, ImChannelContext imChannelContext) {
        String text = loginReqBody.getUserId();
        String key = ImConst.AUTH_KEY;
        String token = Md5.sign(text, key, CHARSET);
        User user = getUser(token, text);
        return user;
    }

    /**
     * 根据token获取用户信息
     *
     * @param token
     * @return
     * @author: WChao
     */
    public User getUser(String token, String userId) {
        //demo中用map，生产环境需要用cache
        User user = tokenMap.get(token);
        if (Objects.nonNull(user)) {
            return user;
        }
        user = StoreHandler.getUserInfo(userId);
        if (user == null ) {
            return null;
        }
        if (tokenMap.size() > 10000) {
            tokenMap.clear();
        }
        tokenMap.put(token, user);
        return user;
    }

    /**
     * 登陆成功返回状态码:ImStatus.C10007
     * 登录失败返回状态码:ImStatus.C10008
     * 注意：只要返回非成功状态码(ImStatus.C10007),其他状态码均为失败,此时用户可以自定义返回状态码，定义返回前端失败信息
     */
    @Override
    public LoginRespBody doLogin(LoginReqBody loginReqBody, ImChannelContext imChannelContext) {
        if (Objects.nonNull(loginReqBody.getUserId())) {
            return LoginRespBody.success();
        } else {
            return LoginRespBody.failed();
        }
    }

    @Override
    public void onSuccess(User user, ImChannelContext channelContext) {
        logger.info("登录成功回调方法");
    }

    @Override
    public void onFailed(ImChannelContext imChannelContext) {
        logger.info("登录失败回调方法");
    }
}
